package com.waqu.common.utils.http;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.waqu.common.utils.collection.ArrayMapTools;
import com.waqu.common.utils.text.StringTools;

/**
 * @Title ConnectGet.java
 * @Package com.waqu.common.utils.http
 * @author Administrator
 * @date 2015年5月25日 下午12:55:25
 * @version V1.0
 */
public class ConnectPost {
	
	private static Logger logger = LoggerFactory.getLogger(ConnectPost.class);
	private static final int default_life_time = 10000;
	private static final int default_time_out = 5000;
	
	public static String send(String url) throws ClientProtocolException, IOException {
		return send(url, true);
	}

	public static String send(String url, boolean showLog) throws ClientProtocolException, IOException {
		return send(url, "UTF-8", showLog);
	}

	public static String send(String url, String charsetName) throws ClientProtocolException, IOException {
		return send(url, charsetName, true);
	}

	public static String send(String url, String charsetName, boolean showLog)
			throws ClientProtocolException, IOException {
		return send(url, null, charsetName, null, showLog);
	}

	public static String send(String url, Map<String, String> params, String charsetName)
			throws ClientProtocolException, IOException {
		return send(url, params, charsetName, true);
	}

	public static String send(String url, Map<String, String> params, String charsetName, boolean showLog)
			throws ClientProtocolException, IOException {
		return send(url, params, charsetName, null, showLog);
	}

	public static String send(String url, Map<String, String> params, String charsetName, Map<String, String> header)
			throws ClientProtocolException, IOException {
		return send(url, params, charsetName, header, true);
	}

	public static String send(String url, Map<String, String> params, String charsetName, Map<String, String> header,
			boolean showLog) throws ClientProtocolException, IOException {
		if (showLog)
			logger.info("URL = {},Parameters = {}", url, params);
		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		// 设置单个连接有效时长
		httpClientBuilder.setConnectionTimeToLive(default_life_time, TimeUnit.MILLISECONDS);
		CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
		String result = null;
		try {
			HttpPost post = new HttpPost(url);
			// 设置请求和传输超时时间
			post.setConfig(RequestConfig.custom().setSocketTimeout(default_time_out).setConnectTimeout(default_time_out).build());
			
			List<NameValuePair> parameters = new ArrayList<>();
			if (ArrayMapTools.isNotEmpty(params)) {
				for (Entry<String, String> entry : params.entrySet()) {
					parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
				}
			}

			// 特殊字符转义
			post.setEntity(new UrlEncodedFormEntity(parameters, charsetName));
			post.setHeader("accept", "*/*");
			post.setHeader("connection", "keep-alive");
			post.setHeader("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0");

			if (ArrayMapTools.isNotEmpty(header)) {
				for (Entry<String, String> entry : header.entrySet())
					post.setHeader(entry.getKey(), entry.getValue());
			}

			HttpResponse response = closeableHttpClient.execute(post);
			String charset = ConnectTools.getCharsetFromResponse(response);
			charsetName = StringTools.isNotEmpty(charset) ? charset : charsetName;
			String _temp = null != response.getEntity()
					? EntityUtils.toString(response.getEntity(), Charset.forName(charsetName)) : null;
			if (showLog)
				logger.info("CODE : {} || Result = {}", response.getStatusLine().getStatusCode(), _temp);
			if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode() && StringTools.isNotEmpty(_temp))
				result = _temp;
		} finally {
			closeableHttpClient.close();
		}
		return result;
	}

	public static String sendBody(String url, String body) throws ClientProtocolException, IOException {
		return sendBody(url, body, true);
	}

	public static String sendBody(String url, String body, String charsetName)
			throws ClientProtocolException, IOException {
		return sendBody(url, body, charsetName, true);
	}

	public static String sendBody(String url, String body, boolean showLog)
			throws ClientProtocolException, IOException {
		return sendBody(url, body, "UTF-8", showLog);
	}

	public static String sendBody(String url, String body, String charsetName, boolean showLog)
			throws ClientProtocolException, IOException {
		return sendBody(url, body, charsetName, null, showLog);
	}

	public static String sendBody(String url, String body, String charsetName, Map<String, String> header,
			boolean showLog) throws ClientProtocolException, IOException {
		if (showLog)
			logger.info("URL = {}, body = {}", url, body);
		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		// 设置单个连接有效时长
		httpClientBuilder.setConnectionTimeToLive(default_life_time, TimeUnit.MILLISECONDS);
		CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
		String result = null;
		try {
			HttpPost post = new HttpPost(url);
			// 设置请求和传输超时时间
			post.setConfig(RequestConfig.custom().setSocketTimeout(default_time_out).setConnectTimeout(default_time_out).build());
			StringEntity entity = new StringEntity(body, charsetName);
			
			post.setEntity(entity);
			post.setHeader("accept", "*/*");
			post.setHeader("connection", "keep-alive");
			post.setHeader("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0");

			if (ArrayMapTools.isNotEmpty(header)) {
				for (Entry<String, String> entry : header.entrySet())
					post.setHeader(entry.getKey(), entry.getValue());
			}

			HttpResponse response = closeableHttpClient.execute(post);
			String charset = ConnectTools.getCharsetFromResponse(response);
			charsetName = StringTools.isNotEmpty(charset) ? charset : charsetName;
			String _temp = null != response.getEntity()
					? EntityUtils.toString(response.getEntity(), Charset.forName(charsetName)) : null;
			if (showLog)
				logger.info("CODE : {} || Result = {}", response.getStatusLine().getStatusCode(), _temp);
			if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode() && StringTools.isNotEmpty(_temp))
				result = _temp;
		} finally {
			closeableHttpClient.close();
		}
		return result;
	}

}
